# -*- coding: utf-8 -*-
from odoo import models, fields, api
from odoo.exceptions import ValidationError, UserError


class DailyPlan(models.Model):
    """日生产计划"""
    _name = 'production.daily.plan'
    _description = '日生产计划'
    _inherit = ['mail.thread', 'mail.activity.mixin']
    _rec_name = 'display_name'
    _order = 'production_date desc, id desc'
    
    # ==================== 基本信息 ====================
    production_date = fields.Date(
        string='生产日期',
        required=True,
        default=fields.Date.today,
        help='计划生产日期'
    )
    
    release_date = fields.Date(
        string='下达日期',
        default=fields.Date.today,
        help='计划下达日期'
    )
    
    company_id = fields.Many2one(
        'res.company',
        string='公司',
        default=lambda self: self.env.company,
        required=True
    )
    
    item_id = fields.Many2one(
        'item.master',
        string='物料',
        required=True,
        help='需要生产的物料'
    )
    
    item_code = fields.Char(
        related='item_id.item_code',
        string='物料编号',
        store=True,
        readonly=True
    )
    
    item_description = fields.Char(
        related='item_id.description1',
        string='物料描述',
        store=True,
        readonly=True
    )
    
    state = fields.Selection([
        ('draft', '草稿'),
        ('confirmed', '已确认'),
        ('in_progress', '生产中'),
        ('done', '已完成'),
        ('cancelled', '已取消'),
    ], string='状态', default='draft', required=True, tracking=True, help='计划状态')
    
    # ==================== 明细行 ====================
    line_ids = fields.One2many(
        'production.daily.plan.line',
        'plan_id',
        string='工序计划明细'
    )
    
    # ==================== 统计信息 ====================
    total_planned_quantity = fields.Float(
        string='总计划数量',
        compute='_compute_totals',
        store=True
    )
    
    total_completed_quantity = fields.Float(
        string='总完成数量',
        compute='_compute_totals',
        store=True
    )
    
    completion_rate = fields.Float(
        string='完成率(%)',
        compute='_compute_totals',
        store=True
    )
    
    operation_count = fields.Integer(
        string='工序数量',
        compute='_compute_totals',
        store=True
    )
    
    # ==================== 显示字段 ====================
    display_name = fields.Char(
        string='显示名称',
        compute='_compute_display_name',
        store=True
    )
    
    # ==================== 计算方法 ====================
    @api.depends('production_date', 'item_code')
    def _compute_display_name(self):
        """计算显示名称"""
        for record in self:
            if record.production_date and record.item_code:
                record.display_name = f"{record.production_date} - {record.item_code}"
            else:
                record.display_name = '新建计划'
    
    @api.depends('line_ids.planned_quantity', 'line_ids.completed_quantity')
    def _compute_totals(self):
        """计算统计信息"""
        for record in self:
            record.operation_count = len(record.line_ids)
            record.total_planned_quantity = sum(record.line_ids.mapped('planned_quantity'))
            record.total_completed_quantity = sum(record.line_ids.mapped('completed_quantity'))
            
            if record.total_planned_quantity > 0:
                record.completion_rate = (record.total_completed_quantity / record.total_planned_quantity) * 100
            else:
                record.completion_rate = 0.0
    
    # ==================== 字段变更 ====================
    @api.onchange('item_id', 'production_date')
    def _onchange_item_generate_operations(self):
        """当物料改变时，自动生成工序明细行"""
        if self.item_id and self.production_date:
            # 清空现有明细行
            self.line_ids = [(5, 0, 0)]
            
            # 查找物料对应的工艺流程
            routings = self.env['production.routing'].search([
                ('routing_code', '=', self.item_id.item_code),
                ('company_id', '=', self.company_id.id),
                ('routing_start_date', '<=', self.production_date),
                '|',
                ('routing_end_date', '=', False),
                ('routing_end_date', '>=', self.production_date),
            ], order='routing_operation')
            
            if not routings:
                # 如果没有找到工艺流程，显示提示
                return {
                    'warning': {
                        'title': '提示',
                        'message': f'未找到物料 {self.item_id.item_code} 在 {self.production_date} 的有效工艺流程。',
                    }
                }
            
            # 生成工序明细行
            lines = []
            for routing in routings:
                lines.append((0, 0, {
                    'routing_operation': routing.routing_operation,
                    'routing_description': routing.routing_description,
                    'routing_workcenter': routing.routing_workcenter,
                    'workcenter_id': routing.workcenter_id.id if routing.workcenter_id else False,
                    'routing_machine': routing.routing_machine,
                    'equipment_id': routing.machine_id.id if routing.machine_id else False,
                    'routing_setup': routing.routing_setup,
                    'routing_run_time': routing.routing_run_time,
                    'routing_yield_percent': routing.routing_yield_percent,
                    'production_date': self.production_date,
                    'planned_quantity': 0.0,
                }))
            
            self.line_ids = lines
    
    # ==================== 业务方法 ====================
    def action_confirm(self):
        """确认计划"""
        for record in self:
            if not record.line_ids:
                raise UserError('请先添加工序计划明细！')
            if any(line.planned_quantity <= 0 for line in record.line_ids):
                raise UserError('所有工序的计划数量必须大于0！')
            record.state = 'confirmed'
    
    def action_start(self):
        """开始生产"""
        for record in self:
            if record.state != 'confirmed':
                raise UserError('只能开始已确认的计划！')
            record.state = 'in_progress'
    
    def action_done(self):
        """完成计划"""
        for record in self:
            record.state = 'done'
    
    def action_cancel(self):
        """取消计划"""
        for record in self:
            record.state = 'cancelled'
    
    def action_draft(self):
        """重置为草稿"""
        for record in self:
            record.state = 'draft'


class DailyPlanLine(models.Model):
    """日生产计划明细（工序级别）"""
    _name = 'production.daily.plan.line'
    _description = '日生产计划明细'
    _rec_name = 'display_name'
    _order = 'routing_operation'
    
    # ==================== 关联信息 ====================
    plan_id = fields.Many2one(
        'production.daily.plan',
        string='生产计划',
        required=True,
        ondelete='cascade'
    )
    
    production_date = fields.Date(
        string='生产日期',
        required=True,
        help='此工序的生产日期'
    )
    
    # ==================== 工艺流程信息（从routing复制） ====================
    routing_operation = fields.Integer(
        string='工序号',
        required=True,
        help='工序编号'
    )
    
    routing_description = fields.Char(
        string='工序描述',
        help='工序描述'
    )
    
    routing_workcenter = fields.Char(
        string='工作中心代码',
        help='工作中心代码'
    )
    
    workcenter_id = fields.Many2one(
        'production.workcenter',
        string='工作中心',
        help='执行此工序的工作中心'
    )
    
    routing_machine = fields.Char(
        string='机器代码',
        help='机器代码'
    )
    
    equipment_id = fields.Many2one(
        'production.equipment',
        string='设备',
        help='执行此工序的设备'
    )
    
    routing_setup = fields.Float(
        string='准备时间(小时)',
        readonly=True,
        help='准备时间（从工艺流程复制）'
    )
    
    routing_run_time = fields.Float(
        string='运行时间(小时)',
        readonly=True,
        help='单件运行时间（从工艺流程复制）'
    )
    
    routing_yield_percent = fields.Float(
        string='良品率(%)',
        readonly=True,
        help='良品率（从工艺流程复制）'
    )
    
    # ==================== 计划数量 ====================
    planned_quantity = fields.Float(
        string='计划数量',
        required=True,
        default=0.0,
        help='计划生产数量'
    )
    
    completed_quantity = fields.Float(
        string='完成数量',
        default=0.0,
        help='实际完成数量'
    )
    
    completion_rate = fields.Float(
        string='完成率(%)',
        compute='_compute_completion_rate',
        store=True
    )
    
    # ==================== 人员安排 ====================
    employee_id = fields.Many2one(
        'hr.employee',
        string='员工',
        help='分配的员工'
    )
    
    employee_code = fields.Char(
        related='employee_id.barcode',
        string='员工代码',
        store=True,
        readonly=True
    )
    
    # ==================== 计算时间和成本 ====================
    estimated_time = fields.Float(
        string='预计时间(小时)',
        compute='_compute_estimated_time',
        store=True,
        help='预计总时间 = 准备时间 + 运行时间 × 计划数量'
    )
    
    estimated_cost = fields.Float(
        string='预计成本',
        compute='_compute_estimated_cost',
        store=True,
        help='预计成本'
    )
    
    # ==================== 状态 ====================
    status = fields.Selection([
        ('pending', '待生产'),
        ('in_progress', '生产中'),
        ('completed', '已完成'),
    ], string='状态', default='pending')
    
    # ==================== 备注 ====================
    notes = fields.Text(string='备注')
    
    # ==================== 显示字段 ====================
    display_name = fields.Char(
        string='显示名称',
        compute='_compute_display_name',
        store=True
    )
    
    # ==================== 计算方法 ====================
    @api.depends('routing_operation', 'routing_description')
    def _compute_display_name(self):
        """计算显示名称"""
        for record in self:
            name = f"工序{record.routing_operation:03d}"
            if record.routing_description:
                name += f" - {record.routing_description}"
            record.display_name = name
    
    @api.depends('planned_quantity', 'completed_quantity')
    def _compute_completion_rate(self):
        """计算完成率"""
        for record in self:
            if record.planned_quantity > 0:
                record.completion_rate = (record.completed_quantity / record.planned_quantity) * 100
            else:
                record.completion_rate = 0.0
    
    @api.depends('routing_setup', 'routing_run_time', 'planned_quantity')
    def _compute_estimated_time(self):
        """计算预计时间"""
        for record in self:
            record.estimated_time = record.routing_setup + (record.routing_run_time * record.planned_quantity)
    
    @api.depends('estimated_time', 'workcenter_id')
    def _compute_estimated_cost(self):
        """计算预计成本"""
        for record in self:
            hourly_cost = record.workcenter_id.costs_hour if record.workcenter_id else 0.0
            record.estimated_cost = record.estimated_time * hourly_cost
    
    # ==================== 约束验证 ====================
    @api.constrains('planned_quantity')
    def _check_planned_quantity(self):
        """验证计划数量"""
        for record in self:
            if record.planned_quantity < 0:
                raise ValidationError('计划数量不能为负数！')
    
    @api.constrains('completed_quantity')
    def _check_completed_quantity(self):
        """验证完成数量"""
        for record in self:
            if record.completed_quantity < 0:
                raise ValidationError('完成数量不能为负数！')

